#include "../aux.h"


int fd;
int fd_ans;
int pid;


/**
 * Prints the menu with the options for a administrator
 */
void ShowMenu(){
	
	system("clear");
	printf("\n"	"***************************************\n"
				"**    ATM MACHINE - XPTO EDITION     **\n"
				"**           ADMIN VERSION           **\n"
				"***************************************\n\n\n");
	
	printf("Choose an operation:\n");
	printf(" 1- Create new client account\n");
  	printf(" 2- Delete account\n");
 	printf(" 3- List accounts\n");
  	printf(" 4- Shutdown server\n");
  	printf(" 5- Exit\n\n");
	
}

/**
 *  Sends a request to the fifo
 */
void SendRequest(Request* req)
{
	write(fd, req, sizeof(Request));
}

void makefifo()
{
   char *strfifo;
   char *i= "ans";

   strfifo = (char *) malloc(256*sizeof(char));

   sprintf(strfifo,"%s%d",i, getpid());
   mkfifo(strfifo, 0660);

   fd_ans = open(strfifo,O_RDWR);
}

void endfifo()
{
	close(fd_ans);
	char *strfifo;
	char *i= "ans";
	strfifo = (char *) malloc(256*sizeof(char));
	sprintf(strfifo,"%s%d",i, getpid());
	unlink(strfifo);
}

void ReceiveFromServer(int TypeOfRequest)
{
	int end=1;

	while(end==1)
	{
		char *str = malloc(sizeof(char)*255);
		readline(fd_ans,str);
		char *feedback;
		char *fim="FIM\n";
		char *ok="Ok\n";

		switch(TypeOfRequest)
		{

			case 1:	//Add account
				if(strcmp(str,ok)>=0)
					feedback="Account successfully added to database.\n";

				else
					feedback="There was a problem adding the new account. Please try again later or contact support.\n";
				end=0;
				write(STDOUT_FILENO, feedback, strlen(feedback));
				break;

			case 2: //Remove account
				if(strcmp(str,ok)>=0)
					feedback="Account successfully removed!\n";

				else
					feedback=str;
				end=0;
				write(STDOUT_FILENO, feedback, strlen(feedback));
				break;

			case 3:	//List accounts
				if(strcmp(str,fim)<0)
				{
					write(STDOUT_FILENO, str, strlen(str));

				}
				else
				{
					feedback="Listing completed.\n";
					write(STDOUT_FILENO, feedback, strlen(feedback));
					end=0;
				}
				break;

			case 4: //Shutdown server
				end=0;
				write(STDOUT_FILENO, str, strlen(str));
				exit(0);
		}
	}
}


/**
 * This function writes in the logfile
 */
void writelogfile(char* op){
	FILE *logfile;
	logfile = fopen("logfile.txt", "a+");
	char actualtime[70];
	char *task=(char*)malloc(256);
	int ch;
	time_t temp;
	struct tm *timeptr;
	temp = time(NULL);
	timeptr = localtime(&temp);
	ch = strftime(actualtime, sizeof(actualtime)-1, "\n20%y-%m-%d %OH:%OM:%OS \0", timeptr);
	sprintf(task, "ADMIN      ");
	strcat(task, op);
	fwrite(actualtime,1, ch, logfile);
	fwrite(task, 1, strlen(task), logfile);
	free(task);
	fclose(logfile);
}


// Admin Operations / Requests

/**
 * Adds a new account to the database
 */
void AddNewAccount(){
	
	char new_client_name[20];
	char new_client_pin[5];
	Request* req = malloc(sizeof(Request));

	printf("\nAccount name: ");
	scanf("%20s", new_client_name);
	CleanStdin();
	printf("\nDesired PIN: ");
	scanf("%4s", new_client_pin);
	CleanStdin();
	
	*req->AccountName=new_client_name;
	*req->pin=new_client_pin;
	req->pid=pid;
	req->type='a';

	SendRequest(req);
	ReceiveFromServer(1);
	endfifo();

}

/**
 * Deletes an account from the database
 */
void DeleteAccount(){
	Request* req = malloc(sizeof(Request));
	int account_number;

	printf("\nAccount number: ");
	scanf("%d", &account_number);
	
	req->AccountNumber=account_number;

	req->pid=pid;
	req->type='r';

	SendRequest(req);
	ReceiveFromServer(2);
	endfifo();
}

/**
 * Lists all the accounts
 */
void ListAccounts(){
	Request* req = malloc(sizeof(Request));
	req->pid=pid;
	req->type='l';

	SendRequest(req);
	ReceiveFromServer(3);
	endfifo();
}

/**
 * Shuts down the server
 */
void ShutServer(){
	Request* req = malloc(sizeof(Request));
	req->pid=pid;
	req->type ='s';

	SendRequest(req);
	ReceiveFromServer(3);
	endfifo();
}

/**
 * The main function
 */
int main(){

	fd=open("requests",O_RDWR);

	if (fd == -1)
	{
		printf("Server is closed! Please, try again later or contact the Administrator\n");
		exit(1);
	}

	pid=getpid();
	printf("Requests FIFO successfully opened.\n");

	ShowMenu();
	int option;
	makefifo();
	
	while (option != 5) {
		
		printf("Operation: ");
		scanf("%d", &option);
		CleanStdin();
	
			switch (option) {
		
				case 1:		//Add a new account
				AddNewAccount();
				break;

				case 2:		//Delete an account
				DeleteAccount();
				break;

				case 3:		//List accounts
				ListAccounts();
				break;

				case 4:		//Shutdown the server
				ShutServer();
				break;
				
				case 5:		//Exit
				printf("The program will now exit.\n");
				break;				

				default:
				printf("Your input is invalid. Please, try again.\n");
				break;
			}
	}

	return 0;
}


